package com.app.web.servlets;

import com.app.common.AppException;
import com.app.common.ResponseResult;
import com.app.pojo.Staff;
import com.app.pojo.User;
import com.app.service.IStaffService;
import com.app.service.IUserService;
import com.app.service.impl.StaffService;
import com.app.service.impl.UserService;
import com.app.utils.UtilTools;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Copyright (C) @2020 fgwang.660@gmail.com
 *
 * @author witt
 * @version 1.0
 * @className UserServlet
 * @date 2020-05-31 18:30
 * @description 用户Servlets
 */

@WebServlet(name = "用户控制层", urlPatterns = { "/login", "/register", "/reset-password", "/users", "/logout" })
public class UserServlet extends HttpServlet {
	private static final long serialVersionUID = 2714233210822769615L;

	/*
	 * 用户业务接口声明注入
	 */
	private final IUserService service = new UserService();

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) {
		switch (request.getServletPath()) {
			/**
			 * 登录相关的请求
			 */
			case "/login":
				// 获取参数
				String loginId = request.getParameter("login_id");
				String password = request.getParameter("password");
				try {
					// 登录逻辑
					User user = service.login(loginId, password);

					HttpSession session = request.getSession();
					session.setAttribute("user", user);

					// 登录成功
					ResponseResult.response(request, response, "index.jsp");
				} catch (AppException e) {
					e.printStackTrace();
					// 登录失败
					ResponseResult.warn(request, response, "登录提示！", e.getMessage(), 3f, "login.jsp");
				} catch (Exception e) {
					// 系统异常
					e.printStackTrace();
					ResponseResult.error(request, response, "登录异常", e, 1.5f, "login.jsp");
				}
				break;
			/**
			 * 注册相关的请求
			 */
			case "/register":
				// 获取参数
				loginId = request.getParameter("login_id");
				password = request.getParameter("password");
				String passwordAgain = request.getParameter("password_again");
				try {
					// 注册逻辑
					Integer n = service.register(loginId, password, passwordAgain);

					// 注册成功
					ResponseResult.info(request, response, "注册提示", "注册成功，你是第" + n + "个注册的用户！", 1.5f, "login.jsp");
				} catch (AppException e) {
					// 注册失败
					ResponseResult.warn(request, response, "注册提示！", e.getMessage(), 2.4f, "register.jsp");
				} catch (Exception e) {
					// 系统异常
					e.printStackTrace();
					ResponseResult.error(request, response, "系统异常", e, 1.5f, "register.jsp");
				}
				break;
			/**
			 * users相关的其它POST请求
			 */
			default:
				switch (request.getParameter("type")) {
					/**
					 * 新增用户(用户通过注册来的，不需要新增)

					 case "new":

					 break;
					 */

					/**
					 * 设置的一定是当前登录用户在设置
					 * 所谓设置，就是改一些用户的信息，比如密码等，改的一定是当前用户的信息而已，所以也是更新，设置是更新的一部分，一种部分更新而已
					 */
					case "setting":
						/**
						 * 修改更新用户，实际上就是更新操作，只不过谁的信息都会改，既然设置也是更新，那这两个分支就是可以合并的，
						 * 因此switch语句不加break;两块代码都会执行
						 */
					case "edit":
						String id = request.getParameter("id");
						String nickName = request.getParameter("nick_name");
						String staffId = request.getParameter("staff_id");
						String disable = request.getParameter("disable");
						/**
						 * 获取id两种方法：
						 * 1.通过登录后的会话获取，设置的时候  用户一定是登录状态，并且服务器会为他分配一个session ,登录成功后，
						 * session中存在这个用户的对象，对象里有当前登录人的id,代码 ((User)request.getSession().getAttribute("user")).getId()
						 *
						 * 2.通过隐藏表单域  给一个input type是hidden ，设置为readonly 或者disabled (只读或者禁用)，值就是session中的id ,然后css ,disabled将其隐藏，后端仍然获取即可，
						 * 建议设置为readonly就好了，disabled估计提交不到
						 *
						 * 下面是第二种方式
						 */
						password = request.getParameter("password");
						try {
							User user = new User()
									.setId(Integer.parseInt(id))
									// 密码不为空  就得加密
									.setPassword(UtilTools.isEmpty(password) ? null : UtilTools.MD5Encoded(password))
									.setNickName(nickName)
									.setStaffId(UtilTools.isEmpty(staffId) ? null : Integer.parseInt(staffId))
									// 将数字转成布尔值 是1 就是true  不是1 就是false
									.setDisable("1".equals(disable));
							service.update(user);
							if(UtilTools.isNotEmpty(password)){
								ResponseResult.info(request, response, "操作提示", "检测到您修改了密码，即将自动退出系统，退出后，请使用新密码重新登录！", 2.5f, "logout");
								return;
							}
							ResponseResult.info(request, response, "操作提示", "个人信息更新成功", 1.5f, "users?type=list");
						} catch (AppException e) {
							ResponseResult.warn(request, response, "操作提示！", e.getMessage(), 2.4f, "users/setting.jsp");
						} catch (Exception e) {
							/**
							 * 字符串解析数字  出现异常  会被这里捕获 NumberFormatException 是Exception的子类
							 * ClassCastException 类型转换异常，服务器异常 都会被捕获
							 */

							e.printStackTrace();
							ResponseResult.error(request, response, "系统异常", e, 1.5f, "index.jsp");
						}
						break;
				}
				break;
		}
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) {
		switch (request.getServletPath()) {
			/**
			 * 退出登录
			 */
			case "/logout":
				HttpSession session = request.getSession();
				// 把会话中已经登录的用户删除
				session.removeAttribute("user");
				// 让会话失效
				session.invalidate();
				// 给用户一个消息提示，倒计时3秒钟 倒计时结束后 跳转到 index.jsp
				ResponseResult.info(request, response, null, "退出成功！", 1f, "index.jsp");
				break;
			/**
			 * 重置密码
			 */
			case "/reset-password":
				// 获取用户名
				String login_id = request.getParameter("login_id");
				try {
					// 返还密码
					String password = service.resetPassword(login_id);
					// 提示用户，10秒后跳转到登录页
					ResponseResult.info(request, response, "操作提示！", "密码重置成功，请牢记您的密码 : <b>" + password + "</b>", 10f, "login.jsp");
				} catch (AppException e) {
					// 提示操作失败
					ResponseResult.warn(request, response, "操作失败！", e.getMessage(), 3f, "login.jsp");
				} catch (Exception e) {
					e.printStackTrace();
					// 系统异常
					ResponseResult.error(request, response, null, e, 2.5f, "index.jsp");
				}
				break;
			/**
			 * users的其它GET请求
			 */
			default:
				switch (UtilTools.isEmpty(request.getParameter("type"))?  "list" : request.getParameter("type") ) {
					/**
					 * 请求查看页面
					 */
					case "view":
						/**
						 * 请求编辑
						 */
					case "edit":
						// 详情id
						String id = request.getParameter("id");
						try {
							// 通过id查用户
							User user = service.get(Integer.parseInt(id));
							IStaffService staffService = new StaffService();
							List<Staff> staffList = staffService.get();
							Map<String, Object> datas = new HashMap<>();
							datas.put("STAFFS",staffList);
							ResponseResult.response(request, response, user,datas, "users/detail.jsp");
						} catch (AppException e) {
							ResponseResult.warn(request, response, "操作失败！", e.getMessage(), 2.4f, "users?type=list");
						} catch (Exception e) {
							e.printStackTrace();
							ResponseResult.error(request, response, null, e, 2.5f, "index.jsp");
						}
						break;
					/**
					 * 请求删除
					 */
					case "delete":
						// 获取数据主键
						id = request.getParameter("id");
						try {
							// service 交互  去删除
							service.delete(id);
							ResponseResult.info(request, response, "操作提示！", "删除成功！", 1f, "users?type=list");
						} catch (AppException e) {
							ResponseResult.warn(request, response, "操作失败！", e.getMessage(), 2f, "users?type=list");
						} catch (Exception e) {
							e.printStackTrace();
							ResponseResult.error(request, response, null, e, 2.5f, "index.jsp");
						}
						break;
					/**
					 * 除去上面的所有，剩下查询全部用户
					 */
					default:
						try {
							// 获取用户列表
							List<User> users = service.get();
							// 把用户列表通过request带到页面，同时显示list页面
							ResponseResult.response(request, response, users, "users/list.jsp");
						} catch (AppException e) {
							ResponseResult.warn(request, response, "操作提示！", e.getMessage(), 2.5f, "index.jsp");
						} catch (Exception e) {
							// 系统异常
							e.printStackTrace();
							ResponseResult.error(request, response, null, e, 2.5f, "index.jsp");
						}
				}
		}
	}
}
